#!/usr/bin/python3
# -*- coding: UTF-8 -*-

import socket
import json
import sys
import serial


def help(cmd):
    print("python3 %s <port>" % cmd)


def parse_cli_info(data):
    # print(data)
    info_dict = json.loads(data)
    # print(info_dict)

    if 'area' in info_dict and 'num' in info_dict and 'dir' in info_dict:
        area = ord(info_dict['area']) - ord('A')
        index = info_dict['num'] - 1
        direct = info_dict['dir']

        if 'prod' in info_dict:
            name = info_dict['prod']
        else:
            name = None

        print("area %d index %d direct %d name %s" % (area, index, direct, name))
    else:
        print("not contain 'area' or 'num' or 'dir'")
        

def socket_send(sendstr):
    # parse_cli_info(sendstr)

    cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    cli.connect(("localhost", 8080))
    cli.send(sendstr.encode())
    cli.close()


class QRReceiver():
    """docstring for QRReceiver"""
    QR_MSG_HEAD = "HEAD-"
    QR_MSG_TAIL = "-TAIL"

    def __init__(self, com='/dev/ttyUSB0', 
                    baudrate=9600, 
                    bytesize=8, 
                    parity='N', 
                    stopbits=1):
        try:
            self.read_timeout = 0.1
            self.serPort = serial.Serial(port=com, 
                                    baudrate=baudrate, 
                                    bytesize=bytesize, 
                                    parity=parity, 
                                    stopbits=stopbits, 
                                    timeout=self.read_timeout)

            self.info_dict = {}
        except:
            print("Open %s failed, please check if in using !" % com)
            if self.serPort != None:
                self.serPort.close()
            os.system("pause")
            exit(-1)
        else:
            print("Open %s success" % com)
        

    def __del__(self):
        if self.serPort != None and self.serPort.isOpen() == True:
            self.serPort.close()
            print("Close uart")


    def serial_send(self, data):
        while self.serPort.writable() == False:
            time.sleep(0.1)
        self.serPort.write(data)


    def check_dir(self, direct):
        if direct == 'E':
            return 1
        elif direct == 'O':
            return 0
        else:
            return -1


    def handler(self, data):
        cnt = 0
        while True:
            print("cnt %d data %s" % (cnt, data))

            pos = data.find(self.QR_MSG_HEAD)
            # print("%s pos %d" % (self.QR_MSG_HEAD, pos))

            if pos == 0:
                if data.find(self.QR_MSG_TAIL) == -1:
                    break

                b = len(self.QR_MSG_HEAD)
                e = data.find(self.QR_MSG_TAIL)

                location = data[b:e]
                print("find location: %s" % location)

                self.info_dict["area"] = location[0]
                self.info_dict['num'] = int(location[1:4])
                self.info_dict['dir'] = self.check_dir(location[5])
                if 'prod' in self.info_dict:
                    del self.info_dict['prod']

                json_str = json.dumps(self.info_dict)
                print(json_str)
                socket_send(json_str)

                data = data[e + len(self.QR_MSG_TAIL):]
            elif pos == -1:
                break
            else:
                e = data.find(self.QR_MSG_HEAD)
                product = data[:e]
                print("find product: %s" % product)

                self.info_dict["prod"] = product

                json_str = json.dumps(self.info_dict)
                print(json_str)
                socket_send(json_str)

                data = data[e:]

            cnt += 1

        return data

    '''
    timeout: 0 will be waiting forever
    '''
    def run(self, timeout):
        datapool = ''
        t_seq = 0
        payload = ''

        if timeout != 0:
            timeout_cnt = timeout / self.read_timeout
        else :
            timeout_cnt = 1

        while timeout_cnt != 0:
            if timeout != 0:
                timeout_cnt -= 1

            if self.serPort.isOpen() == False:
                print("something wrong with COM port, exit!")
                break

            if self.serPort.readable() == False:
                print('serial port is not readable')
                time.sleep(self.read_timeout)
                continue

            data = self.serPort.read(256)
            if not data:
                # print("len(datapool) %d" % len(datapool))
                # print(datapool)
                
                if datapool == "\r\n":
                    datapool = ''
                elif len(datapool) > 0 and datapool.find(self.QR_MSG_HEAD) < 0 and datapool.find(self.QR_MSG_TAIL) < 0:
                    product = datapool
                    print("remaining find product: %s" % product)

                    self.info_dict["prod"] = product

                    json_str = json.dumps(self.info_dict)
                    print(json_str)
                    socket_send(json_str)

                    datapool = ''

                continue 

            datapool = '{}{}'.format(datapool, bytes.decode(data))
            datapool = self.handler(datapool)


def TestData(area, num, sdir):
    info_dict = {}
    info_dict['area'] = area
    info_dict['num'] = num
    info_dict['dir'] = sdir

    if sdir:
        info_dict['prod'] = 'HSD\n%d' % num

    json_str = json.dumps(info_dict)
    print(json_str)
    socket_send(json_str)


def main(serial_port):
    print("open port %s" % serial_port)
    port = QRReceiver(com=serial_port, baudrate=9600)
    port.run(0)


if __name__ == '__main__':
    if len(sys.argv) != 2:
        help(sys.argv[0])
        exit(-1)

    main(sys.argv[1])

    # TestData('D', 50, 0)
